﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using System.Threading;

namespace AppUpgrader.Deploy
{
    public class DeployWorker:AbstractWorker
    {
        private String zipFilePath { get; set; }
        public void Asyn_DeployZipFile(String zipFilePath)
        {
            this.zipFilePath = zipFilePath;
            Thread th = new Thread(new ThreadStart(DeployZipFile));
            th.Start();
        }
        private void DeployZipFile()
        {
            try
            {
                String zipFilePath = this.zipFilePath;
                if (String.IsNullOrWhiteSpace(zipFilePath))
                    throw new ArgumentNullException("zipFilePath");
                if (!File.Exists(zipFilePath))
                    throw new ArgumentException("cannot find update file:" + zipFilePath);

                String tempPath = Path.GetTempPath();
                String DeployTempPath = Path.Combine(tempPath, Guid.NewGuid().ToString());
                Directory.CreateDirectory(DeployTempPath);

                LogUtils.WriteDebug(String.Format("准备解压文件{0}到临时目录{1}", zipFilePath, DeployTempPath));
                this.RaiseStateChanged(new StateChangedEventArgs() { Message = "正在解压缩更新包" });
                bool ret = UnZipFile(zipFilePath, DeployTempPath);

                this.RaiseStateChanged(new StateChangedEventArgs() { Message = "正在更新......" });
                String targetDir = AppDomain.CurrentDomain.BaseDirectory;
                LogUtils.WriteDebug(String.Format("准备拷贝临时目录文件{0}到安装目录{1}", DeployTempPath, targetDir));
                CopyFiles(DeployTempPath, targetDir);

                this.RaiseStateChanged(new StateChangedEventArgs() { Message = "正在清理临时文件......" });
                LogUtils.WriteDebug(String.Format("准备清理临时目录{0}", DeployTempPath));
                Directory.Delete(DeployTempPath,true);

                this.RaiseComplete(new StateChangedEventArgs() { Message="更新已完成"});
            }
            catch (Exception ex)
            {
                this.RaiseException(ex);
            }
        }

        private bool UnZipFile(String zipFile,String unZipDir)
        {
            try  
            {  
                using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFile)))  
                {  
                    ZipEntry theEntry;  
                    while ((theEntry = s.GetNextEntry()) != null)
                    {  
                        string directoryName = Path.GetDirectoryName(theEntry.Name);  
                        string fileName = Path.GetFileName(theEntry.Name);
                        if(!String.IsNullOrWhiteSpace(directoryName))  
                        {
                            String dir = Path.Combine(unZipDir, directoryName);
                            if(!Directory.Exists(dir))
                                Directory.CreateDirectory(dir);
                        }
                        if (!String.IsNullOrWhiteSpace(fileName))
                        {
                            String filePath = Path.Combine(unZipDir, theEntry.Name);
                            using (FileStream streamWriter = File.Create(filePath))
                            {  
                                int size = 2048;  
                                byte[] data = new byte[2048];  
                                while (true)  
                                {  
                                    size = s.Read(data, 0, data.Length);  
                                    if (size > 0)  
                                    {  
                                        streamWriter.Write(data, 0, size);  
                                    }  
                                    else  
                                    {  
                                        break;  
                                    }  
                               }  
                            }  
                        }  
                    }//while  
                }  
            }  
            catch (Exception ex)  
            {
                throw ex;  
            }  
            return true;  
        }//解压结束  

        private void CopyFiles(String SRCDir,String TargetDir)
        {
            if (!Directory.Exists(SRCDir))
                return;
            if (!Directory.Exists(TargetDir))
                Directory.CreateDirectory(TargetDir);

            DirectoryInfo di = new DirectoryInfo(SRCDir);
            DirectoryInfo[] childDirs = di.GetDirectories();
            if (childDirs != null && childDirs.Length > 0)
            {
                foreach (var dir in childDirs)
                {
                    String DirName = dir.Name;
                    String tarDir = Path.Combine(TargetDir,DirName);
                    CopyFiles(dir.FullName, tarDir);
                }
            }

            FileInfo[] files = di.GetFiles();
            if (files != null && files.Length > 0)
            {
                foreach (var file in files)
                {
                    String fileName = file.Name;
                    String tarFile = Path.Combine(TargetDir,fileName);
                    File.Copy(file.FullName, tarFile, true);
                }
            }
        }
    }
}
